#include "pch.h"
#include "D3DShape.h"
#include "VertexLayout.h"
#include <vector>

using namespace DXBase;
using namespace DXBase::D3D;

using namespace Platform;
using namespace Microsoft::WRL;

using namespace std;

void Shape::Validate(VertexLayout^ layout)
{
	if (pVertices->Size != pVStrides->Size)
		throw ExHelper::CreateException(ErrorCodes::ShapeVerticesBufferHaveDifferentSize);

	vector<uint32> sizes;
	for (uint32 i = 0; i < layout->Elements->Size; i++)
	{
		auto desc = layout->Elements->GetAt(i);
		if (desc.InputSlot > 16) // this is just preposterous, no?!?!
			throw ref new InvalidArgumentException();
		if(desc.InputSlot >= sizes.size())
			sizes.resize(desc.InputSlot+1);
		auto size = desc.AlignedByteOffset + GetSize(desc.Format);
		if (size > sizes[desc.InputSlot])
			sizes[desc.InputSlot] = size;
	}
	if (pVertices->Size < sizes.size())
		throw  ExHelper::CreateException(ErrorCodes::ShapeDoNotHaveEnoughVertexBuffer);

	for (uint32 i = 0; i < pVStrides->Size; i++)
	{
		if (sizes[i] != 0 && sizes[i] != pVStrides->GetAt(i))
			throw  ExHelper::CreateException(ErrorCodes::ShapeStrideDoesntMatchVertexLayout);
	}

	auto getc = [this](int index) -> uint32 { return pVertices->data[index]->ByteSize / pStrides->data[index]; };
	auto N = pVertices->Size;
	if (N < 2)
		return;
	auto N0 = getc(0);
	for (uint32 i = 2; i < N; i++)
		if (getc(i) != N)
			throw ExHelper::CreateException(ErrorCodes::ShapeVerticesBufferHaveDifferentSize);
}
